﻿/**
* 防抖函数
* @param {*} func 需要防抖处理的函数。
* @param {*} wait 延迟执行的时间，单位毫秒。
* @param {*} immediate  一个布尔值，当为 true 时，无论是否在等待时间内，都会立即执行一次 func 函数。
*/
function debounce(func, wait, immediate) {
    let timeout, args, context, timestamp, result;

    const later = function () {
        // 据上一次触发时间间隔
        const last = +new Date() - timestamp;

        // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
        if (last < wait && last > 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };

    return function (...args) {
        context = this;
        timestamp = +new Date();
        const callNow = immediate && !timeout;
        // 如果延时不存在，重新设定延时
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }

        return result;
    };
}
Vue.prototype.debounce = debounce;
/**
* window.localStorage 浏览器永久缓存
* @method set 设置永久缓存
* @method get 获取永久缓存
* @method remove 移除永久缓存
* @method clear 移除全部永久缓存
*/
Vue.prototype.Storage = {
    // 查看 v2.4.3版本更新日志
    setKey(key) { return `webapp:${key}`; },
    // 设置永久缓存
    set(key, val) { window.localStorage.setItem(this.setKey(key), JSON.stringify(val)); },
    // 获取永久缓存
    get(key) { let json = window.localStorage.getItem(this.setKey(key)); return JSON.parse(json); },
    // 移除永久缓存
    remove(key) { window.localStorage.removeItem(this.setKey(key)); },
    // 移除全部永久缓存
    clear() { window.localStorage.clear(); },
};

Vue.prototype.i18n = {
    currentLang: navigator.language,
    messages: {
        zhCN: {"confirmexit": "确认退出?", "tips": "提示", "determine": "确定", "cancel": "取消", "changepassword": "修改密码", "logout": "退出", "aresureclose": "确认关闭?", "browserversionlow": "您的浏览器版本过低，无法显示报表内容！建议升级浏览器或更换浏览器！", "pleaseenter": "请输入", "pleasechoose": "请选择", "pleaseenternumber": "请输入数字", "pleaseselectdatetime": "请选择日期时间", "pleaseselectdate": "请选择日期", "pleaseselecttime": "请选择时间", "addnew": "新增","refresh": "刷新","query": "查询","confirmdelete": "确定删除","operation": "操作","viewrecord": "查看记录","modifyrecord": "修改记录","deleterecord": "删除记录",},
        enUS: {"confirmexit": "Confirm to exit?", "tips": "Tips", "determine": "determine", "cancel": "cancel", "changepassword": "Change Password", "logout": "sign out", "aresureclose": "Are you sure to close?", "browserversionlow": "Your browser version is too low to display report content! Suggest upgrading or changing your browser!", "browserversionlow": "Your browser version is too low to display report content! Suggest upgrading or changing your browser!", "pleaseenter": "Please enter", "pleasechoose": "Please choose", "pleaseenternumber": "please enter a number", "pleaseselectdatetime": "Please select a date and time", "pleaseselectdate": "Please select a date", "pleaseselecttime": "Please select a time", "addnew": "Add new","refresh": "Refresh","query": "Query","confirmdelete": "Confirm delete","operation": "Operation","viewrecord": "View record","modifyrecord": "Modify record","deleterecord": "Delete record",},
        frFR: {"confirmexit": "Confirmer le retrait?", "tips": "Conseils", "determine": "Déterminer", "cancel": "Annulation", "changepassword": "Modifier le mot de passe", "logout": "Quitter", "aresureclose": "Confirmer la fermeture?", "browserversionlow": "La version de votre navigateur est trop basse pour afficher le contenu du rapport! Il est recommandé de mettre à jour votre navigateur ou de le remplacer!", "browserversionlow": "La version de votre navigateur est trop basse pour afficher le contenu du rapport! Il est recommandé de mettre à jour votre navigateur ou de le remplacer!", "pleaseenter": "Veuillez entrer", "pleasechoose": "Veuillez sélectionner", "pleaseenternumber": "Veuillez entrer un numéro", "pleaseselectdatetime": "Veuillez sélectionner une date heure", "pleaseselectdate": "Veuillez sélectionner une date", "pleaseselecttime": "Veuillez sélectionner une heure", "addnew": "Ajouter nouveau","refresh": "Rafraîchir","query": "Requête","confirmdelete": "Confirmer la suppression","operation": "Opération","viewrecord": "Afficher l'enregistrement","modifyrecord": "Modifier l'enregistrement","deleterecord": "Supprimer l'enregistrement",},
        jaJP: {"confirmexit": "終了を確認しますか？", "tips": "ヒント", "determine": "を選択して、", "cancel": "キャンセル", "changepassword": "パスワードの変更", "logout": "終了", "aresureclose": "閉じることを確認しますか？", "browserversionlow": "ブラウザのバージョンが低すぎて、レポートの内容を表示できません！ブラウザをアップグレードするか、ブラウザを交換することをお勧めします！", "pleaseenter": "入力してください", "pleasechoose": "選択してください", "pleaseenternumber": "数字を入力してください", "pleaseselectdatetime": "日時を選択してください", "pleaseselectdate": "日付を選択してください", "pleaseselecttime": "時間を選択してください", "addnew": "新規追加","refresh": "更新","query": "検索","confirmdelete": "削除確認","operation": "操作","viewrecord": "記録の確認","modifyrecord": "記録の修正","deleterecord": "記録の削除",},
        viVN: {"confirmexit": "Xác nhận rút lui?", "tips": "Mẹo", "determine": "Xác định", "cancel": "Hủy bỏ", "changepassword": "Thay đổi mật khẩu", "logout": "Thoát", "aresureclose": "Xác nhận đóng cửa?", "browserversionlow": "Phiên bản trình duyệt của bạn quá thấp để hiển thị nội dung báo cáo! Đề nghị nâng cấp trình duyệt hoặc thay thế nó!", "pleaseenter": "Vui lòng nhập", "pleasechoose": "Vui lòng chọn", "pleaseenternumber": "Vui lòng nhập số", "pleaseselectdatetime": "Vui lòng chọn ngày giờ", "pleaseselectdate": "Vui lòng chọn ngày", "pleaseselecttime": "Vui lòng chọn thời gian", "addnew": "Thêm mới","refresh": "Làm mới","query": "Tìm kiếm","confirmdelete": "Xác nhận xóa","operation": "Thao tác","viewrecord": "Xem hồ sơ","modifyrecord": "Sửa đổi hồ sơ","deleterecord": "Xóa hồ sơ",},
        zhHK: {"confirmexit": "确认退出？", "tips": "显示", "determine": "肯定", "cancel": "取消", "changepassword": "修改密码", "logout": "退出", "aresureclose": "确认关闭？", "browserversionlow": "你浏览器版本过低，无法显示报表内容！建议升浏览器或者更换浏览器！", "browserversionlow": "你浏览器版本过低，无法显示报表内容！建议升浏览器或者更换浏览器！", "pleaseenter": "请输入", "pleasechoose": "唔该拣", "pleaseenternumber": "请输入数字", "pleaseselectdatetime": "唔该选择日期时间", "pleaseselectdate": "唔该选择日期。", "pleaseselecttime": "唔该选择时间", "addnew": "新增","refresh": "刷新","query": "查询","confirmdelete": "确定删除","operation": "操作","viewrecord": "查看记录","modifyrecord": "修改记录","deleterecord": "删除记录",},
        zhTW: {"confirmexit": "確認退出？", "tips": "提示", "determine": "確定", "cancel": "取消", "changepassword": "修改密碼", "logout": "退出", "aresureclose": "確認關閉？", "browserversionlow": "您的流覽器版本過低，無法顯示報表內容！ 建議陞級瀏覽器或更換瀏覽器！", "browserversionlow": "您的流覽器版本過低，無法顯示報表內容！ 建議陞級瀏覽器或更換瀏覽器！", "pleaseenter": "請輸入", "pleasechoose": "請選擇", "pleaseenternumber": "請輸入數位", "pleaseselectdatetime": "請選擇日期時間", "pleaseselectdate": "請選擇日期", "pleaseselecttime": "請選擇時間", "addnew": "新增","refresh": "刷新","query": "查詢","confirmdelete": "確定刪除","operation": "操作","viewrecord": "查看記錄","modifyrecord": "修改記錄","deleterecord": "刪除記錄",}
    },
    t(key) {
        const langCode = (this.currentLang || lang).replace('-', '');
        return this.messages[langCode] ? this.messages[langCode][key] : '';
    },
};
Vue.prototype.Message=ELEMENT.Message;
Vue.prototype.Alert= { 
    success(msg,fuc){ type='success'; if(fuc){fuc.type=type; ELEMENT.MessageBox.alert(msg,"系统信息",fuc); }else{ELEMENT.MessageBox.alert(msg,"系统信息",{ type});} },
    
    warning(msg,fuc){ type='warning'; if(fuc){fuc.type=type; ELEMENT.MessageBox.alert(msg,"系统信息",fuc); }else{ELEMENT.MessageBox.alert(msg,"系统信息",{ type});} },
    
    error(msg,fuc){ type='error'; if(fuc){fuc.type=type; ELEMENT.MessageBox.alert(msg,"系统信息",fuc); }else{ELEMENT.MessageBox.alert(msg,"系统信息",{ type});} },
    
    info(msg,fuc){ type='info'; if(fuc){fuc.type=type; ELEMENT.MessageBox.alert(msg,"系统信息",fuc); }else{ELEMENT.MessageBox.alert(msg,"系统信息",{ type});} },
   
 };
Vue.prototype.Notification =ELEMENT.Notification ;
 
/** 管理系统布局组件  
<el-admin logo-src="/img/logo.png"
  logo-title="订单管理系统"
  :menu-data="menuData"
  user-name=""
  user-avatar=""
  v-on:handle-edit-pass=""
  v-on:handle-logout=""
  v-bind:background-color="backgroundColor"
  v-bind:text-color="textColor"
  v-bind:active-text-color="activeTextColor">
  <div style="border:2px solid #0094ff;width:100%;height:100%;" >内容</div>
</el-admin> 
 
menuData: [{ title: "导航1", path: "/d1", icon: "el-icon-menu",submenu: [ { title: "导航2",path: "/d2",icon: "el-icon-location",},{ title: "导航3",path: "/d3",icon: "el-icon-setting",}] },]
*/
Vue.component('ElAdmin', {
    data() {
        return {
            isCollapse: false,
            breadcrumbList: [],
        }
    },
    methods: {
        Logout() {
            if (this.handleLogout === undefined) {
                this.$confirm(this.i18n.t("confirmexit"), this.i18n.t("tips"), { confirmButtonText: this.i18n.t("determine"), cancelButtonText: this.i18n.t("cancel"), type: 'warning' }).then(() => { }).catch(() => { })
            } else { this.handleLogout(); }
        },
        handleOpen(p, s) { this.breadcrumbList = [p, s]; },
        handleCollapse() { this.isMenuOpen = !this.isMenuOpen; this.isCollapse = this.isMenuOpen; },
    },
    props: {
        logoSrc: String,// logo 地址
        logoTitle: String,// 应用名称
        handleEditPass: Function,// 修改密码方法
        handleLogout: Function,// 退出登录方法
        menuData: Array,// 菜单数据
        currentPath: String,// 当前打开地址

        userName: String,// 用户名
        userAvatar: String,// 用户头像
        editPassTxt: { type: String, default: "", },// 修改密码文本
        loginOutTxt: { type: String, default: "", },// 退出登录文本
        showBreadcrumb: { type: Boolean, default: false },// 显示 打开路径地址
        backgroundColor: { type: String, default: "#304156", required: false },// 菜单背景颜色
        textColor: { type: String, default: "#fff", required: false },// 文本颜色
        activeTextColor: { type: String, default: "#409eff", required: false },// 选中文本颜色
    },
    template:
        `
<div class="el-admin">
    <div class="layout-aside" v-bind:class="{collapse:isCollapse}" v-bind:style="{ backgroundColor:backgroundColor,color:textColor}" >
        <div class="layout-logo">
            <div>
                <img v-bind:src="logoSrc" alt="logo" v-if="logoSrc" />
                <span v-show="!isCollapse">{{logoTitle}}</span>
            </div>
        </div>
        <el-scrollbar class="sidebar-scroll">
            <el-menu v-bind:default-active="currentPath" v-bind:collapse="isCollapse"
                        v-bind:background-color="backgroundColor"
                        v-bind:text-color="textColor"
                        v-bind:active-text-color="activeTextColor"
                        style="border:none">
                <el-submenu v-for="(item, index) in menuData" v-bind:index="item.path" v-bind:key="item.path">
                    <template slot="title">
                        <i v-bind:class="item.icon"></i>
                        <span slot="title">{{item.title}}</span>
                    </template>
                    <el-menu-item v-for="(sub, sindex) in item.submenu" v-bind:index="sub.path" v-bind:key="sub.path">
                        <template slot="title">
                            <i v-bind:class="sub.icon"></i>
                            <a slot="title" v-on:click="handleOpen(item,sub)">{{sub.title}}</a>
                        </template>
                    </el-menu-item>
                </el-submenu>
            </el-menu>
        </el-scrollbar>
    </div>
    <div class="layout-container" v-bind:class="{collapse:isCollapse}">
        <div class="layout-header" v-bind:class="{collapse:isCollapse}">
            <div class="header-wrapper">
                <div class="header-left">
                    <div class="open-icon" v-on:click="handleCollapse" style="margin: 0 9px 0 0;">
                        <i class="el-icon-s-fold" v-if="!isCollapse"></i>
                        <i class="el-icon-s-unfold" v-if="isCollapse"></i>
                    </div>
                    <el-breadcrumb separator=">" v-if="showBreadcrumb">
                        <template v-for="(item,index) in breadcrumbList">
                            <el-breadcrumb-item v-bind:key="index" v-if="item.title">{{item.title}}</el-breadcrumb-item>
                        </template>
                    </el-breadcrumb>
                </div><div class="header-right">
                    <span class="header-user" v-if="userName">{{ userName }}</span>
                    <el-dropdown trigger="click" v-if="userName">
                        <span class="el-dropdown-link">
                            <img :src="userAvatar" style="height:40px" alt="avatar" v-if="userAvatar" />
                            <i class="el-icon-arrow-down el-icon--right"></i>
                        </span>
                        <el-dropdown-menu>
                            <el-dropdown-item icon="el-icon-edit" v-on:click.native="handleEditPass" v-if="handleEditPass !== undefined">
                               {{editPassTxt}}
                            </el-dropdown-item>
                            <el-dropdown-item icon="el-icon-close" v-on:click.native="Logout">{{loginOutTxt||i18n.t('logout')}}</el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </div>
            </div>
        </div>
        <div class="layout-main">
            <div class="app-main">
                <div name="fade-transfrom" mode="out-in">
                    <slot></slot>
                </div>
            </div>
        </div>
    </div>
</div>
`
});
/** 头布局组件
<el-extend-header 
    logo-src="/img/logo.png" 
    logo-title="订单管理系统" 
    :menu-data="menuData" 
    :active-index="activeIndex" 
    user-name="百里东君" 
    user-avatar="" 
    login-out-txt="">
</el-extend-header> 

menuData: [{ title: "周期作业", path: "/dashboard" },{ title: "执行日志", path: "/log" },{ title: "作业分析", path: "/period" },{ title: "设置", path: "/setting" },{ title: "Info", path: "/Info" },],
activeIndex: "/dashboard",
*/
Vue.component('ElExtendHeader', {
    props: {
        logoSrc: String,
        logoTitle: String,
        activeIndex: { type: String, },
        menuData: Array,
        userName: String,
        userAvatar: String,
        loginOutTxt: String,
        handleLogout: Function,
    },
    template: `<el-header class="extend">
    <div class="header-wrapper el-menu-horizontal">
        <div class="header-left">
            <el-menu :default-active="activeIndex" mode="horizontal">
                <el-menu-item tabindex="-1">
                    <div><img v-bind:src="logoSrc" style="height:40px;margin-right:5px;" v-bind:alt="logoTitle"><span>{{logoTitle}}</span></div>
                </el-menu-item>
                <el-menu-item :index="item.path" :key="idx" v-for="(item,idx) in menuData"><a v-bind:href="item.path">{{item.title}}</a></el-menu-item>
            </el-menu>
        </div>
        <div class="header-right">
            <span class="header-user" v-if="userName">{{ userName }}</span>
            <el-dropdown trigger="click" v-if="userName">
                <span class="el-dropdown-link">
                    <img :src="userAvatar" style="height:40px;" alt="avatar" v-if="userAvatar" />
                    <i class="el-icon-arrow-down el-icon--right" v-if="loginOutTxt"></i>
                </span>
                <el-dropdown-menu>
                    <el-dropdown-item icon="el-icon-close" v-on:click.native="handleLogout" v-if="loginOutTxt">{{loginOutTxt}}</el-dropdown-item>
                    <slot></slot>
                </el-dropdown-menu>
            </el-dropdown>
        </div>
    </div></el-header>`
});
/** 对话框扩展组件  
<el-extend-dialog :dialog-visible="dialogVisible" :submit="submitForm" :cancel="handleClose"></el-extend-dialog> 

dialogVisible: false,
handleClose(e) { this.dialogVisible = e;},
handleClose(e) { this.dialogVisible = e;},

submitForm(e) {
    var that = this;
    that.$refs["dialogForm"].validate((valid) => {
        if (valid) {
            //todo...
        }
    });
},
*/
Vue.component('ElExtendDialog', {
    data() {
        return {
            localDialogVisible: this.dialogVisible
        };
    },
    methods: {
        handleClose(done) {
            if (this.closeConfirm) {
                this.$confirm(this.i18n.t('aresureclose'),this.i18n.t("tips"), {type: 'warning',customClass:"elmessagebox"}).then(_ => { done(); this.close(false); }).catch(_ => { });
            } else {
                this.close(false);
            }
        },
        close(e) {
            this.localDialogVisible = false;
            this.cancel(false);
        },
    },
    watch: {
        dialogVisible(newVal, oldVal) {
            this.localDialogVisible = newVal;
        }
    },
    props: {
        buttonSize: { type: String, default: "small", },
        dialogTitle: { type: String, },
        closeConfirm: { type: Boolean, default: true, },
        dialogWidth: { type: String, default: "40%", },
        dialogVisible: { type: Boolean, default: false, required: true },
        footerVisible: { type: Boolean, default: false, },
        submit: { type: Function, required: true },
        cancel: { type: Function, required: true },
    },
    template: `
        <el-dialog v-bind:title="dialogTitle||i18n.t('tips')" v-bind:visible.sync="localDialogVisible" :before-close="handleClose" left :width="dialogWidth">
            <slot></slot>
            <div slot="footer" class="dialog-footer" v-show="footerVisible">
                <el-button v-on:click="close" v-bind:size="buttonSize">{{i18n.t('cancel')}}</el-button>
                <el-button type="primary" v-on:click="submit" v-bind:size="buttonSize">{{i18n.t('determine')}}</el-button>
                <slot name="footerButton"></slot>
            </div>
        </el-dialog>`
});
/**
    <el-extend-form :form-json="formJson" :submit="submitForm" :form-data="formData" v-loading.fullscreen.lock="loading"
                    :dialog-width="dialogWidth" :dialog-visible="dialogVisible" :cancel="handleClose" :footer-visible="footerVisible"></el-extend-form>
  dialogTitle:"",
  dialogVisible: false,
  footerVisible: true, 
  dialogWidth: "30%",
  buttonSize: "small",

  loading: false,
  formData: {},
  formJson: [
      {type: 'input',label: '大大姓名',prop: 'name',default: '', // 默认值为空字符串
          rules: [{ required: true, message: '姓名不能为空', trigger: 'blur' }]},
      { type: 'select', label: '性别', prop: 'gender', default: null, // 对于选择类型，默认值可以设置为 null
          options: [{ label: '男', value: 'male' },{ label: '女', value: 'female' }],rules: [{ required: true, message: '性别不能为空' }]
      }, 
      {type: 'switch',label: '是否同意',prop: 'isAgree',default: false, // 开关默认状态为 false，表示关闭
      rules: [{ required: true, message: '请确认是否同意', trigger: 'change' }]},
      {type: 'datetimepicker',label: '预约时间',prop: 'appointmentTime',default: null, // 可以设置默认值，也可以不设置
          placeholder: '请选择预约时间',format: 'yyyy-MM-dd HH:mm:ss',valueFormat: 'yyyy-MM-dd HH:mm:ss',dateTimePickerType: 'datetime', // 可以是 'date' | 'datetime' | 'year' | 'month' | 'time' 等rules: [    { required: true, message: '预约时间不能为空', trigger: 'change' }]},
      {
          type: 'number', // 新增的数字输入框类型
          label: '数量',prop: 'quantity',min: 1, // 最小值
          max: 100, // 最大值
          step: 1, // 步长
          placeholder: '请输入数量', // 占位符
          default: 1, // 默认值
          rules: [{ required: true, message: '数量不能为空', trigger: 'blur' },{ type: 'number', message: '数量必须为数字', trigger: 'blur' }]
      },
      {type: 'radio',label: '爱好',prop: 'hobby', default: undefined, // 单选默认值可以设置为 undefined 或第一个选项的值
          options: [    { label: '足球', value: 'soccer' },    { label: '篮球', value: 'basketball' }],rules: [{ required: true, message: '请选择爱好', trigger: 'change' }]},
      {type: 'checkbox',label: '技能',prop: 'skills', default: [], // 多选默认值应为数组
          options: [{ label: '编程', value: 'coding' },{ label: '设计', value: 'design' },{ label: '测试', value: 'test' },{ label: '部署', value: 'uat' },],rules: [{ required: true, message: '请选择至少一个技能', trigger: 'change' }]
      }
  ],

  handleClose(e) {  this.dialogVisible = e;  },
  submitForm(data) {},
  loadData(index, row) {   var that = this;   that.dialogVisible = true;   that.formData = {};},

 * 
 */
Vue.component('ElExtendForm', {
    data() {
        return {
            localDialogVisible: this.dialogVisible,
            form: {},
        }
    },
    props: {
        formJson: Array,
        formData: { required: false },

        buttonSize: { type: String, default: "small", },
        dialogTitle: { type: String, },
        closeConfirm: { type: Boolean, default: true, },
        dialogWidth: { type: String, default: "40%", },
        dialogVisible: { type: Boolean, default: false, required: true },
        footerVisible: { type: Boolean, default: false, },
        submit: { type: Function, required: true },
        cancel: { type: Function, required: true },
    },
    computed: {
        formRules() {
            const rules = {};
            this.formJson.forEach(item => {
                rules[item.prop] = item.rules || [];
            });
            return rules;
        }
    },
    created() {
        this.initForm();
    },
    watch: {
        dialogVisible(newVal, oldVal) {
            this.localDialogVisible = newVal;
        },
        formData(n, o) {
            this.form = n;
        }
    },
    methods: {
        handleClose(done) {
            if (this.closeConfirm && this.footerVisible) {
                this.$confirm(this.i18n.t('aresureclose'),this.i18n.t("tips"), {type: 'warning',customClass:"elmessagebox"}).then(_ => { done(); this.close(false); }).catch(_ => { });
            } else {
                this.close(false);
            }
        },
        close(e) {
            this.localDialogVisible = false;
            this.cancel(false);
        },
        initForm() {
            if (!this.formData) { this.form = this.formData; }
            else { this.formJson.forEach(item => { this.$set(this.form, item.prop, item.default); }); }
        },
        submitForm() {
            this.$refs["formRef"].validate((valid) => {
                if (valid) {
                    this.submit(this.form);
                }
            });
        },
    },
    filters: {
        placeholderFilter(s, p) { return s + p; }
    },
    template: `
<el-dialog v-bind:title="dialogTitle||i18n.t('tips')" v-bind:visible.sync="localDialogVisible" :before-close="handleClose" left :width="dialogWidth">

    <el-form v-if="form" :model="form" :rules="formRules" ref="formRef" size="small" label-width="6em">
    <el-row>
    <el-col :span="12" v-for="(item, index) in formJson" :key="index">
        <el-form-item :key="index" :label="item.label" :prop="item.prop">
            <!-- 输入框 -->
            <template v-if="item.type === 'input'">
                <el-input v-model="form[item.prop]" v-bind:placeholder="i18n.t('pleaseenter')" autocomplete="off" class="elmy"></el-input>
            </template>
            <!-- 下拉选择 -->
            <template v-if="item.type === 'select'">
                <el-select v-model="form[item.prop]" v-bind:placeholder="i18n.t('pleasechoose')" class="elmy">
                    <el-option v-for="option in item.options"
                               :key="option.value"
                               :label="option.label"
                               :value="option.value"></el-option>
                </el-select>
            </template>
            <!-- 单选按钮 -->
            <template v-if="item.type === 'radio'">
                <el-radio-group v-model="form[item.prop]">
                    <el-radio v-for="radio in item.options"
                              :label="radio.value"
                              :key="radio.value" border>
                        {{ radio.label }}
                    </el-radio>
                </el-radio-group>
            </template>
            <!-- 多选框 -->
            <template v-if="item.type === 'checkbox'" class="elmy">
                <el-checkbox-group v-model="form[item.prop]">
                    <el-checkbox-button v-for="checkbox in item.options"
                                        :label="checkbox.value"
                                        :key="checkbox.value" border>
                        {{ checkbox.label }}
                    </el-checkbox-button>
                </el-checkbox-group>
            </template>
            <!-- 数字输入框 -->
            <template v-if="item.type === 'number'">
                <el-input-number v-model="form[item.prop]"
                                 :min="item.min || 1"
                                 :max="item.max || 10"
                                 :step="item.step || 1"
                                 :placeholder="item.placeholder || i18n.t('pleaseenternumber')" class="elmy">
                </el-input-number>
            </template>
            <!-- 日期时间选择器 -->
            <template v-if="item.type === 'datetimepicker'">
                <el-date-picker v-model="form.appointmentTime"
                                :type="item.dateTimePickerType || 'datetime'"
                                :placeholder="item.placeholder || i18n.t('pleaseselectdatetime')"
                                :format="item.format || 'YYYY-MM-DD HH:mm:ss'"
                                :value-format="item.valueFormat || 'timestamp'">
                </el-date-picker>
            </template>
            <!-- 开关控件 -->
            <template v-if="item.type === 'switch'">
                <el-switch v-model="form[item.prop]" class="elmy"></el-switch>
            </template>
        </el-form-item>
        <slot></slot>
        </el-col>
        </el-row>
    </el-form>

    <div slot="footer" class="dialog-footer" v-show="footerVisible" v-if="form">
        <el-button v-on:click="close" v-bind:size="buttonSize">{{i18n.t('cancel')}}</el-button>
        <el-button type="primary" v-on:click="submitForm" v-bind:size="buttonSize">{{i18n.t('determine')}}</el-button>
        <slot name="footerButton"></slot>
    </div>
</el-dialog>`
});
/**
<el-main>
   <el-extend-search :load-data="handleLoadData" :add="handleAdd" :filter-json="filterJson"
   :show-search="true"
   :show-add="true"
   :show-refresh="true"
   ></el-extend-search>

filterJson: [
{"type": "input","label": "大大姓名","prop": "name","default": ""},
{"type": "select","label": "性别","prop": "gender","default": null,"options": [    { "label": "男", "value": "male" },    { "label": "女", "value": "female" }]},
{"type": "switch","label": "是否同意","prop": "isAgree","default": false},
{"type": "datetimepicker","label": "预约时间","prop": "appointmentTime","default": null,"placeholder": "请选择预约时间","format": "yyyy-MM-dd HH:mm:ss","valueFormat": "yyyy-MM-dd HH:mm:ss","dateTimePickerType": "datetime"},                      
{"type": "radio","label": "爱好","prop": "hobby","default": undefined,"options": [    { "label": "足球", "value": "soccer" },    { "label": "篮球", "value": "basketball" }    // 可以添加更多选项]},
{"type": "checkbox","label": "技能","prop": "skills","default": [],"options": [    { "label": "编程", "value": "coding" },    { "label": "设计", "value": "design" },    { "label": "测试", "value": "test" },    { "label": "部署", "value": "uat" },]}
],

handleAdd() { },
handleLoadData(data) {console.log(data) }
 */
Vue.component('ElExtendSearch', {
    props: {
        filterJson: Array,
        openAddDialog: Function,
        search: Function,
        buttonSize: { type: String, default: "small", },
    },
    data() {
        return {
            filter: {},
        }
    },
    created() {
        this.initForm();
    },
    methods: {
        initForm() {
            this.filterJson.forEach(item => { this.$set(this.filter, item.prop, item.default); });
        },
        localOpenAddDialog(e) {this.initForm(); this.openAddDialog(null,e); },
        localSearch() {
            this.search({ filter: this.filter });
        },
        localRefresh() {
            this.initForm();
            this.search({ filter: this.filter });
        }
    },
    filters: {
        lableFilter(data) {
            return data + " :";
        }
    },
    template: `
<el-row type="flex" align="center">
    <el-col :span="19">
        <el-form :inline="true" :model="filter" ref="filterRef" :size="buttonSize" label-width="6em">
            <el-form-item v-for="(item, index) in filterJson" :key="index" :label="item.label|lableFilter" :prop="item.prop" label-suffix=":sss">
                <!-- 输入框 -->
                <template v-if="item.type === 'input'">
                    <el-input v-model="filter[item.prop]" :placeholder="i18n.t('pleaseenter')" autocomplete="off"></el-input>
                </template>
                <!-- 下拉选择 -->
                <template v-if="item.type === 'select'">
                    <el-select v-model="filter[item.prop]" :placeholder="i18n.t('pleasechoose')">
                        <el-option v-for="option in item.options"
                                   :key="option.value"
                                   :label="option.label"
                                   :value="option.value"></el-option>
                    </el-select>
                </template>
                <!-- 单选按钮 -->
                <template v-if="item.type === 'radio'">
                    <el-radio-group v-model="filter[item.prop]" class="elmy">
                        <el-radio v-for="radio in item.options"
                                  :label="radio.value"
                                  :key="radio.value">
                            {{ radio.label }}
                        </el-radio>
                    </el-radio-group>
                </template>
                <!-- 多选框 -->
                <template v-if="item.type === 'checkbox'">
                    <el-checkbox-group v-model="filter[item.prop]">
                        <el-checkbox-button v-for="checkbox in item.options"
                                            :label="checkbox.value"
                                            :key="checkbox.value" border class="elmy">
                            {{ checkbox.label }}
                        </el-checkbox-button>
                    </el-checkbox-group>
                </template>
                <!-- 日期时间选择器 -->
                <template v-if="item.type === 'datetimepicker'">
                    <el-date-picker v-model="filter.appointmentTime"
                                    :type="item.dateTimePickerType || 'datetime'"
                                    :placeholder="item.placeholder || i18n.t('pleaseselectdatetime')"
                                    :format="item.format || 'YYYY-MM-DD HH:mm:ss'"
                                    :value-format="item.valueFormat || 'timestamp'">
                    </el-date-picker>
                </template>
                <!-- 开关控件 -->
                <template v-if="item.type === 'switch'">
                    <el-switch v-model="filter[item.prop]" class="elmy"></el-switch>
                </template>
            </el-form-item>
            <slot></slot>
        </el-form>   
    </el-col>
    <el-col :span="5" style="text-align: right;">
    <el-button type="primary" size="mini" icon="el-icon-search" v-on:click="localSearch" v-if="search !== undefined">{{this.i18n.t('query')}}</el-button>
    <el-button type="primary" size="mini" icon="el-icon-plus" v-on:click="localOpenAddDialog" v-if="openAddDialog !== undefined">{{i18n.t('addnew')}}</el-button>
    <el-button type="default" size="mini" icon="el-icon-refresh" v-on:click="localRefresh" v-if="search !== undefined">{{i18n.t('refresh')}}</el-button>
    </el-col>
</el-row>`
});
/**
<el-row type="flex" align="center">
 <el-col :span="24" style="padding: 10px 0 0 0;">
     <el-extend-table :columns="columns"
     :tool-visible="false"
     :table-data="tableData"
     primary-key="name"
     :load-data="loadData"
     :handle-detail="handleEdit"
     :handle-edit="handleEdit"
     :handle-delete="handleEdit"
     :page-sizes=[]
     ></el-extend-table>
 * 
tableData: [{ date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles',},],
columns: [{prop: "date",label: "日期",width: 180}, ],
handleEdit(e) {}
 */
Vue.component('ElExtendTable', {
    data() {
        return {
            localToolVisible: false,
            tableQuery: {
                pageNo: 1,
                pageSize: 10,
                pageSizes: this.pageSizes,
            },
            localTotalRows:0,
        }
    },
    created() {
        this.localToolVisible = this.toolVisible || !((this.viewDetail === undefined) || (this.handleEdit === undefined) || (this.handleDelete === undefined));
    },
    methods: {
        handleSizeChange(val) { this.tableQuery.pageNo = 1; this.tableQuery.pageSize = val; this.loadData({ curry: this.tableQuery }); },
        handleCurrentChange(val) { this.tableQuery.pageNo = val; this.loadData({ curry: this.tableQuery }); },
        localHandleDetail(e) {
            this.viewDetail(e)
        },
        localHandleEdit(e) {
            this.handleEdit(e)
        },
        localHandleDelete(e) {
            this.$confirm(this.i18n.t('confirmdelete'), this.i18n.t('tips'), { confirmButtonText: this.i18n.t('determine'), cancelButtonText: this.i18n.t('cancel')  , type: 'error', customClass: "elmessagebox" }).then(() => {
                this.handleDelete(e);
            }).catch(_ => { console.info(_); })
        },
    },
    props: {
        emptyText: String,
        size: String,
        columns: Array,
        tableData: Array,
        totalRows: { type: Number, default: 0, },
        primaryKey: { type: String, default: "id", },

        loadData: Function,
        prevText:{type:String,required:false},
        nextText:{type:String,required:false},
        toolVisible: { type: Boolean, default: false },
        viewDetail: Function,
        handleEdit: Function,
        handleDelete: Function,

        pageSizes: { type: Array, default: function () { return [10, 20, 30, 40, 50]; }, required: false },
    },
    mounted() {
        this.localTotalRows = this.totalRows;
        this.tableQuery.pageSizes = this.pageSizes;
    },
    //watch: {
    //    pageSizes(newVal, oldVal) {
    //        if (newVal) { this.tableQuery.pageSizes = newVal; }
    //    },
    //    totalRows(n, o) { this.localTotalRows = n; console.log(n,o ) }
    //},
    template: `<div>
        <el-table :data="tableData"
                  style="width: 100%;margin-bottom:15px;" size="size" stripe border
                  empty-text="emptyText" class="elmy">
            <el-table-column type="index" align="center">
            </el-table-column>
            <el-table-column v-for="(column, index) in columns"
                             :key="index"
                             :prop="column.prop"
                             :label="column.label"
                             :align="column.textAlign"
                             :fixed="column.fixed"
                             :show-overflow-tooltip="column.showOverflowTooltip"
                             :width="column.width"
                             :formatter="column.formatter">
                             </el-table-column>
            <slot></slot>
            <el-table-column width="260" :label="i18n.t('operation')" fixed="right" v-if="localToolVisible">
                <template slot-scope="scope">
                    <slot name="header"></slot>
                    <el-tooltip :content="i18n.t('viewrecord')" placement="bottom" v-if="viewDetail !== undefined">
                        <el-button type="default" size="mini" icon="el-icon-view" v-on:click="localHandleDetail({index:scope.$index,key:scope.row[primaryKey],row:scope.row})"></el-button>
                    </el-tooltip>
                    <el-tooltip :content="i18n.t('modifyrecord')" placement="bottom" v-if="handleEdit !== undefined">
                        <el-button type="primary" size="mini" icon="el-icon-edit" v-on:click="localHandleEdit({index:scope.$index,key:scope.row[primaryKey],row:scope.row})"></el-button>
                    </el-tooltip>
                    <el-tooltip :content="i18n.t('deleterecord')" placement="bottom" v-if="handleDelete !== undefined">
                        <el-button type="danger" size="mini" icon="el-icon-delete-solid" v-on:click="localHandleDelete({index:scope.$index,key:scope.row[primaryKey],row:scope.row})"></el-button>
                    </el-tooltip>
                    <slot name="footer"></slot>
                </template>
            </el-table-column>
        </el-table>
        <el-pagination v-on:size-change="handleSizeChange" v-on:current-change="handleCurrentChange" 
        :current-page="tableQuery.pageNo" :page-sizes="tableQuery.pageSizes" 
        :page-size="tableQuery.pageSize" 
        :prev-text="prevText" 
        :hide-on-single-page="false"
        :next-text="nextText"
        layout="total, sizes, prev, pager, next, jumper"
        :total="localTotalRows"></el-pagination>
        </div>`
});


/**
          <el-table-list :button-size="buttonSize" v-loading.fullscreen.lock="fullscreenLoading"
                       :dialog-visible="dialogVisible"
                       :filter-json="filterJson"
                       :table-data="tableData"
                       :columns="columns"
                       :total-rows="totalRows"
                       :prev-text="prevText"
                       :next-text="nextText"
                       :dialog-width="dialogWidth"
                       :form-json="formJson"
                       :load-data="handleLoadData"
                       :delete="handleDelete"
                       :submit="submitForm"
                       :detail="viewDetailDialog"></el-table-list>

var $taskVue = new Vue({
     el: "#main",
     data() {
         return {
             fullscreenLoading: false,
             prevText: "上一页",
             nextText: "下一页",
             buttonSize: "small",

             filterJson: [
                 {
                     "type": "input",
                     "label": "大大姓名",
                     "prop": "name",
                     "default": ""
                 },
                 {
                     "type": "select",
                     "label": "性别",
                     "prop": "gender",
                     "default": null,
                     "options": [
                         { "label": "男", "value": "male" },
                         { "label": "女", "value": "female" }
                     ]
                 },
                 {
                     "type": "switch",
                     "label": "是否同意",
                     "prop": "isAgree",
                     "default": false
                 },
                 {
                     "type": "datetimepicker",
                     "label": "预约时间",
                     "prop": "appointmentTime",
                     "default": null,
                     "placeholder": "请选择预约时间",
                     "format": "yyyy-MM-dd HH:mm:ss",
                     "valueFormat": "yyyy-MM-dd HH:mm:ss",
                     "dateTimePickerType": "datetime"
                 },
                 {
                     "type": "radio",
                     "label": "爱好",
                     "prop": "hobby",
                     "default": undefined,
                     "options": [
                         { "label": "足球", "value": "soccer" },
                         { "label": "篮球", "value": "basketball" }
                     ]
                 },
                 {
                     "type": "checkbox",
                     "label": "技能",
                     "prop": "skills",
                     "default": [],
                     "options": [
                         { "label": "编程", "value": "coding" },
                         { "label": "设计", "value": "design" },
                         { "label": "测试", "value": "test" },
                         { "label": "部署", "value": "uat" },
                     ]
                 }
             ],
             tableData: [
                 {
                     "name": "张三2",
                     "appointmentTime": "2024-08-22",
                     "gender": "male",
                     "isAgree": true,
                     "quantity": 10,
                     "hobby": "soccer",
                     "skills": ["coding", "design"]
                 }, {
                     "name": "张三",
                     "appointmentTime": "2024-08-22",
                     "gender": "male",
                     "isAgree": true,
                     "quantity": 10,
                     "hobby": "soccer",
                     "skills": ["coding", "design"]
                 },
                 {
                     "name": "李四",
                     "appointmentTime": "2024-08-23",
                     "gender": "female",
                     "isAgree": false,
                     "quantity": 5,
                     "hobby": "basketball",
                     "skills": ["design", "test"]
                 },
                 {
                     "name": "王五",
                     "appointmentTime": "2024-08-24",
                     "gender": "male",
                     "isAgree": true,
                     "quantity": 20,
                     "hobby": "soccer",
                     "skills": ["coding", "uat"]
                 },
                 {
                     "name": "赵六",
                     "appointmentTime": "2024-08-25",
                     "gender": "female",
                     "isAgree": true,
                     "quantity": 15,
                     "hobby": "basketball",
                     "skills": ["coding", "design", "test"]
                 },
                 {
                     "name": "孙七",
                     "appointmentTime": "2024-08-26",
                     "gender": "male",
                     "isAgree": false,
                     "quantity": 5,
                     "hobby": "soccer",
                     "skills": ["test", "uat"]
                 },
                 {
                     "name": "周八",
                     "appointmentTime": "2024-08-27",
                     "gender": "female",
                     "isAgree": true,
                     "quantity": 10,
                     "hobby": "basketball",
                     "skills": ["coding", "design"]
                 },
                 {
                     "name": "吴九",
                     "appointmentTime": "2024-08-28",
                     "gender": "male",
                     "isAgree": true,
                     "quantity": 20,
                     "hobby": "soccer",
                     "skills": ["design", "test", "uat"]
                 },
                 {
                     "name": "郑十",
                     "appointmentTime": "2024-08-29",
                     "gender": "female",
                     "isAgree": false,
                     "quantity": 15,
                     "hobby": "basketball",
                     "skills": ["coding", "uat"]
                 },
                 {
                     "name": "王十一",
                     "appointmentTime": "2024-08-30",
                     "gender": "male",
                     "isAgree": true,
                     "quantity": 25,
                     "hobby": "soccer",
                     "skills": ["coding", "design", "test"]
                 },
                 {
                     "name": "陈十二",
                     "appointmentTime": "2024-08-31",
                     "gender": "female",
                     "isAgree": true,
                     "quantity": 30,
                     "hobby": "basketball",
                     "skills": ["coding", "design", "test", "uat"]
                 }
             ],
             columns: [
                 {
                     prop: "name",
                     label: "姓名", textAlign: "center",
                     width: 180
                 },
                 {
                     prop: "appointmentTime",
                     label: "预约时间",
                     width: 180
                 },
                 {
                     prop: "gender",
                     label: "性别", textAlign: "center",
                     width: 180
                 }, {
                     prop: "isAgree",
                     label: "是否同意", textAlign: "center",
                     formatter: (row, column, cellValue) => {
                         return cellValue ? `是` : `否`;
                     },

                     width: 180
                 }, {
                     prop: "quantity",
                     label: "数量", textAlign: "center",
                     width: 180
                 },
                 {
                     prop: "hobby", showOverflowTooltip: true,
                     label: "爱好"
                 }, {
                     prop: "skills", showOverflowTooltip: true,
                     label: "技能"
                 },
             ],

             dialogVisible: false,
             footerVisible: true,
             dialogWidth: "40%",


             loading: false,
             formData: {},
             formJson: [{
                 type: 'input',
                 label: '大大姓名',
                 prop: 'name',
                 default: '', // 默认值为空字符串
                 rules: [{ required: true, message: '姓名不能为空', trigger: 'blur' }]
             },
             {
                 type: 'select',
                 label: '性别',
                 prop: 'gender', default: null, // 对于选择类型，默认值可以设置为 null
                 options: [
                     { label: '男', value: 'male' },
                     { label: '女', value: 'female' }
                 ],
                 rules: [{ required: true, message: '性别不能为空' }]
             },
             {
                 type: 'switch',
                 label: '是否同意',
                 prop: 'isAgree',
                 default: false, // 开关默认状态为 false，表示关闭
                 rules: [{ required: true, message: '请确认是否同意', trigger: 'change' }]
             },
             {
                 type: 'datetimepicker',
                 label: '预约时间',
                 prop: 'appointmentTime',
                 default: null, // 可以设置默认值，也可以不设置
                 placeholder: '请选择预约时间',
                 format: 'yyyy-MM-dd HH:mm:ss',
                 valueFormat: 'yyyy-MM-dd',
                 dateTimePickerType: 'datetime', // 可以是 'date' | 'datetime' | 'year' | 'month' | 'time' 等
                 rules: [
                     { required: true, message: '预约时间不能为空', trigger: 'change' }
                 ]
             },
             {
                 type: 'number', // 新增的数字输入框类型
                 label: '数量',
                 prop: 'quantity',
                 min: 1, // 最小值
                 max: 100, // 最大值
                 step: 1, // 步长
                 placeholder: '请输入数量', // 占位符
                 default: 1, // 默认值
                 rules: [{ required: true, message: '数量不能为空', trigger: 'blur' },
                 { type: 'number', message: '数量必须为数字', trigger: 'blur' }]
             },
             {
                 type: 'radio',
                 label: '爱好',
                 prop: 'hobby', default: undefined, // 单选默认值可以设置为 undefined 或第一个选项的值
                 options: [
                     { label: '足球', value: 'soccer' },
                     { label: '篮球', value: 'basketball' }
                     // 可以添加更多选项
                 ],
                 rules: [{ required: true, message: '请选择爱好', trigger: 'change' }]
             },
             {
                 type: 'checkbox',
                 label: '技能',
                 prop: 'skills', default: [], // 多选默认值应为数组
                 options: [
                     { label: '编程', value: 'coding' },
                     { label: '设计', value: 'design' },
                     { label: '测试', value: 'test' },
                     { label: '部署', value: 'uat' },
                 ],
                 rules: [{ required: true, message: '请选择至少一个技能', trigger: 'change' }]
             }
             ],
         }
     },
     created() { this.handleLoadData(); },
     mounted: function () { },
     methods: {
         handleLoadData(e) {
             console.log("查询条件", e);
             this.totalRows = this.tableData.length;
         },
         handleDelete(e) {
             console.log("handleDelete", e);
         },
         submitForm(data) {
             console.log("表单提交方法", data);
             this.dialogVisible = true;
             this.$message({ message: "表单提交方法", center: true, type: 'success' });
         },
         viewDetailDialog(e) {
             console.info("viewDialogForm 打开详情弹窗方法")
         },
     },
     filters: {
         
     }
 });
 **/
Vue.component('ElTableList', {
    data() {
        return {
            filter: {},

            localDialogVisible: false,
            footerVisible: true,

            loading: false,
            initFormData: {},
            formData: {},
            dialogTitle:"操作-提示"
        }
    },
    props: {
        buttonSize: String,
        filterJson: Array,
        tableData: Array, 
        totalRows: { type: Number, default: 0, },
        columns: Array,
        dialogWidth: String,
        formJson: Array,
        dialogVisible: Boolean,

        prevText: { type: String, required: false },
        nextText: { type: String, required: false },
        loadData: Function,
        delete: Function,
        submit: Function,
        detail: Function,
    },
    //mounted() {
    //    this.localDialogVisible = this.dialogVisible;
    //    this.tableQuery.pageSizes = this.pageSizes;
    //},
    watch: {
        dialogVisible(n, o){ this.localDialogVisible = n; }
    },
    created() { this.initForm(); },
    methods: {
        initForm() {
            this.formJson.forEach(item => { this.$set(this.formData, item.prop, item.default); });
            this.initFormData = this.formData;
        },
        handleOpenDialog(e) {
            this.footerVisible = true;
            if (e) { this.formData = e.row; }
            else { this.formData = this.initFormData; }
            this.localDialogVisible = true;
        },
        handleClose(e) {
            this.localDialogVisible = e;
        },
        handleLoadData(e) {
            if (e) {
                this.filter = e.filter;
            }
            this.loadData(e);
        },
        handleDelete(e) {
            return this.delete(e);
        },
        submitForm(data) {
            this.submit(data);
        },
        viewDetailDialog(e) {
            if (e) { this.formData = e.row;}
            this.footerVisible = false;
            this.localDialogVisible = this.dialogVisible;
            this.detail(e);
        },
    },
    template: `
    <div>
<el-main>
<el-row type="flex" align="center">
<el-extend-search 
:search="handleLoadData"
:open-add-dialog="handleOpenDialog"
:button-size="buttonSize"
:filter-json="filterJson"
:show-search="true"
:show-add="true"
:show-refresh="true"><slot name="search"></slot>
</el-extend-search>
</el-row>
<el-row type="flex" align="center">
<el-col :span="24" style="padding: 10px 0 0 0;">
    <el-extend-table 
    :columns="columns"
    :tool-visible="false"
    :table-data="tableData"
    :total-rows="totalRows"
    :prev-text="prevText" 
    :next-text="nextText"
     primary-key="name"
    :load-data="handleLoadData"
    :view-detail="viewDetailDialog"
    :handle-edit="handleOpenDialog"
    :handle-delete="handleDelete"><slot name="columns"></slot></el-extend-table>
</el-col>
</el-row>
</el-main>
<el-extend-form 
:form-json="formJson"
:button-size="buttonSize"
:submit="submitForm"
:form-data="formData"
:dialog-title="dialogTitle"
 v-loading.fullscreen.lock="loading"
:close-confirm="true"
:dialog-width="dialogWidth"
:dialog-visible="localDialogVisible" :cancel="handleClose" :footer-visible="footerVisible"><slot name="form"></slot></el-extend-form>
</div>`
});

/* 弹出页面扩展--使用方式
** <el-open dialogTitle="信息" v-bind:dialogvisible="dialogVisible" url="/home/privacy" v-on:cancel="onClose" ></el-open>
*/
Vue.component('el-open-web', {
    props: {
        dialogtitle: { type: String, default: "", },//  弹窗宽度，百分比。默认50%
        dialogvisible: { type: Boolean, required: true, default: false },  //  是否可视
        dialogtop: { type: [Number, String], default: "5vh", },//  弹窗宽度，百分比。默认50%
        dialogwidth: { type: [Number, String], default: "50%", },//  弹窗宽度，百分比。默认50%
        dialogstyle: { type: String, default: "width:100%;height:300px;", },//  弹窗宽度，百分比。默认50%
        url: { type: String, required: true, default: "", },//  弹窗宽度，百分比。默认50%

    },
    data() {
        return {
            isVisible: this.dialogvisible, //弹出框
        }
    }
    , methods: {
        onCancel() {
            this.$emit("cancel");
            this.$emit("update:dialogvisible", false);
        },
        handleClose(done) {
            this.$confirm(this.i18n.t('aresureclose'), this.i18n.t("tips"), { type: 'warning', customClass: "elmessagebox" }).then(_ => {
                done();
                this.$emit("cancel");
                this.$emit("update:dialogvisible", false);
            }).catch(_ => { });
        }
    },
    watch: {
        dialogvisible() {
            this.isVisible = this.dialogvisible;
        }
    },
    template: `
<el-dialog :title="dialogtitle||i18n.t('tips')" type="base-dialog-form" :visible="isVisible" :width="dialogwidth" :top="dialogtop" :close-on-click-modal="false" :before-close="handleClose" :close="onCancel">
<iframe :src="url" frameborder="0" width="100%" :style="dialogstyle"></iframe>
    <span slot="footer" class="dialog-footer">
        <el-button v-on:click="onCancel" size="small" v-if="showCancel">{{i18n.t('cancel')}}</el-button>
        <el-button type="primary" v-on:click="onSubmit" size="small" v-if="showSubmit">{{i18n.t('determine')}}</el-button>
    </span>
</el-dialog> `,
   
});

/* 弹出页面扩展--使用方式
** <el-open dialogTitle="信息" v-bind:dialogvisible="dialogVisible" url="/home/privacy" v-on:submit="oonSubmit" v-on:cancel="onClose" ></el-open>
*/
Vue.component('el-open', {
    template: `
<el-dialog :title="dialogtitle||i18n.t('tips')" type="base-dialog-form" :visible="isVisible" :width="dialogwidth" :top="dialogtop" :close-on-click-modal="false" :before-close="handleClose" :close="onCancel">
<iframe :src="url" frameborder="0" width="100%" :style="dialogstyle"></iframe>
    <span slot="footer" class="dialog-footer">
        <el-button v-on:click="onCancel" size="small" v-if="showCancel">{{i18n.t('cancel')}}</el-button>
        <el-button type="primary" v-on:click="onSubmit" size="small" v-if="showSubmit">{{i18n.t('determine')}}</el-button>
    </span>
</el-dialog> `,
    props: {
        dialogtitle: { type: String, default: "", },//  弹窗宽度，百分比。默认50%
        showsubmit: { type: Boolean, default: true },  //  是否可视
        showcancel: { type: Boolean, default: true },  //  是否可视
        dialogvisible: { type: Boolean, required: true, default: false },  //  是否可视
        dialogtop: { type: [Number, String], default: "5vh", },//  弹窗宽度，百分比。默认50%
        dialogwidth: { type: [Number, String], default: "50%", },//  弹窗宽度，百分比。默认50%
        dialogstyle: { type: String, default: "width:100%;height:300px;", },//  弹窗宽度，百分比。默认50%
        url: { type: String, required: true, default: "", },//  弹窗宽度，百分比。默认50%
    },
    data() {
        return {
            isVisible: this.dialogvisible, //弹出框
            showSubmit: this.showsubmit,
            showCancel: this.showcancel
        }
    }
    , methods: {
        onCancel() {
            this.$emit("cancel");
            this.$emit("update:dialogvisible", false);
        },
        onSubmit() {
            this.$emit("submit");
            this.$emit("update:dialogvisible", false);
        },
        handleClose(done) {
            this.$confirm(this.i18n.t('aresureclose'),this.i18n.t("tips"), {type: 'warning',customClass:"elmessagebox"}).then(_ => {
                done();
                this.$emit("cancel");
                this.$emit("update:dialogvisible", false);
            }).catch(_ => { });
        }
    },
    watch: {
        dialogvisible() {
            this.isVisible = this.dialogvisible;
        }
    }
});

/*  *弹出页面扩展1*
使用、
1、添加组件：<el-openurl dialogtitle="信息" v-bind:dialogvisible="dialogVisible" url="/home/privacy" :close="onClose"></el-openurl> 

2、父组件添加生命周期：
mounted(){window.addEventListener('message', this.handleMessage);},// 监听message事件 获取子组件传过来的值
beforeDestroy(){ window.removeEventListener('message', this.handleMessage);},// 在组件销毁前移除事件监听器

3、在methods中添加方法
handleMessage(event){ const data = event.data; if (data) { this.dialogVisible = data.dialogVisible; } },

4、子组件使用：
在methods中添加方法
postMessage(data){window.parent.postMessage(data,"*");},//data为传给父组件的值 一般包含 dialogVisible 变量

5、在提交的方法中使用、 this.postMessage({ dialogVisible: false }) //可传更多数据 如 { dialogVisible: false，fromData:obj }
*/
Vue.component('el-openurl', {
    props: {
        dialogtitle: { type: String, default: "", },//  弹窗宽度，百分比。默认50%
        dialogvisible: { type: Boolean, required: true, default: false },  //  是否可视
        dialogtop: { type: [Number, String], default: "5vh", },//  弹窗宽度，百分比。默认50%
        dialogwidth: { type: [Number, String], default: "50%", },//  弹窗宽度，百分比。默认50%
        dialogstyle: { type: String, default: "width:100%;height:380px;", },//  弹窗宽度，百分比。默认50%
        url: { type: String, required: true, default: "", },//  弹窗宽度，百分比。默认50%
        close: () => { dialogvisible = false },
    },
    data() {
        return {
            isVisible: this.dialogvisible, //弹出框
        }
    },
    methods: {
        onClose() {
            this.$emit("close");//this.isVisible = false;
        },
        beforeClose(done) {
            this.$confirm(this.i18n.t('aresureclose'),this.i18n.t("tips"), {type: 'warning',customClass:"elmessagebox"}).then(_ => {
                done(); this.$emit("close"); //this.isVisible = false;
            }).catch(_ => { });
        }
    },
    mounted() {
        this.dialogvisible = this.isVisible;
    },
    watch: {
        dialogvisible(v) { this.isVisible = v; }
    },
    template: `
<el-dialog :title="dialogtitle||i18n.t('tips')" :visible="isVisible" :width="dialogwidth" :top="dialogtop" :close-on-click-modal="true" :show-close="true" :before-close="beforeClose" :close="onClose">
<iframe ref="iframe" :src="url" width="100%" :style="dialogstyle" style="border:none;" class="iframe" frameborder="0" scrolling="yes" name="iframe" seamless>{{i18n.t('browserversionlow')}}</iframe>
</el-dialog> `,
});

/* *弹出页面扩展2*

使用、
1、添加组件：<el-openfrom dialogtitle="信息2" ref="iframe" v-bind:dialogvisible="dialogVisible" url="/demotwo/detail" v-on:submit="submitForm" v-on:close="onClose" :showcancel="true" :showsubmit="true"></el-openfrom>

父组件添加：
2、在methods添加方法：openWin(func, parameter) {const iframe = this.$refs.iframe.$refs.iframe.contentWindow; iframe[func](parameter) },
在需要调用的地方使用：this.openWin('submitForm', 'data') //submitForm为子组件的提交方法名  data为传过去的参数

子组件使用：
3、添加方法  
loadFunc(funcName) { window[funcName] = (v) => { this[funcName](v); }; },
frameVisible(parentVueName) {window.parent[parentVueName].$data.dialogVisible = false;}, 

4、使用  created 中添加 this.loadFunc("submitForm"); //submitForm 提交方法名
5、在提交的方法中使用 this.frameVisible("myvue");// myvu为父组件vue的名称 示例: var myvue=new Vue(...);
*/
Vue.component('el-openfrom', {
    props: {
        dialogtitle: { type: String, default: "", },//  弹窗宽度，百分比。默认50%
        dialogvisible: { type: Boolean, required: true, default: false },  //  是否可视
        showsubmit: { type: Boolean, default: true },  //  是否可视
        showcancel: { type: Boolean, default: true },  //  是否可视
        dialogtop: { type: [Number, String], default: "5vh", },//  弹窗宽度，百分比。默认50%
        dialogwidth: { type: [Number, String], default: "50%", },//  弹窗宽度，百分比。默认50%
        dialogstyle: { type: String, default: "width:100%;height:380px;", },//  弹窗宽度，百分比。默认50%
        url: { type: String, required: true, default: "", },//  弹窗宽度，百分比。默认50%
        close: () => { dialogvisible = false },
        submit: () => { },
    },
    data() {
        return {
            isVisible: this.dialogvisible, //弹出框
            showSubmit: this.showsubmit,
            showCancel: this.showcancel
        }
    },
    methods: {
        onClose() {
            this.$emit("close");
        },
        onSubmit() {
            this.$emit("submit");
        },
        beforeClose(done) {
            this.$confirm(this.i18n.t('aresureclose'),this.i18n.t("tips"), {type: 'warning',customClass:"elmessagebox"}).then(_ => { done(); this.$emit("close"); }).catch(_ => { });
        }
    },
    mounted() {
        this.dialogvisible = this.isVisible;
    },
    watch: {
        dialogvisible(v) { this.isVisible = v; },
        showsubmit(v) { this.showSubmit = v; },
        showcancel(v) { this.showCancel = v; },
    },
    template: `
<el-dialog :title="dialogtitle||i18n.t('tips')" :visible="isVisible" :width="dialogwidth" :top="dialogtop" :close-on-click-modal="true" :show-close="true" :before-close="beforeClose" :close="onClose">
    <iframe ref="iframe" :src="url" width="100%" :style="dialogstyle" style="border:none;" class="iframe" frameborder="0" scrolling="yes" name="iframe" id="iframe" seamless>{{i18n.t('browserversionlow')}}</iframe>
    <div slot="footer" class="dialog-footer">
        <el-button v-on:click="onClose" size="small" v-if="showCancel">{{i18n.t('cancel')}}</el-button><el-button type="primary" v-on:click="onSubmit" size="small" v-if="showSubmit">{{i18n.t('determine')}}</el-button>
    </div>
</el-dialog>`
});










